﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using MediatR;
using Casamiel.API.Infrastructure.Filters;
using Casamiel.Domain.Request.Waimai;
using Casamiel.Domain.Response;
using Casamiel.API.Infrastructure;
using Casamiel.Application.Commands.Pre;
using Newtonsoft.Json;
using System.Globalization;
using Casamiel.Domain.Entity;
using Casamiel.Common;
using Casamiel.Common.Extensions;
using Casamiel.Application;
using Enyim.Caching;
using Microsoft.Extensions.Options;
using Casamiel.API.Application.Services;
using Casamiel.API.Application.Models.ICModels;
using Newtonsoft.Json.Linq;
using Casamiel.Domain.Response.Pre;
using Casamiel.Domain.Request.Pre;
using Casamiel.Domain.Request;
using Casamiel.Application.Commands.Wechat;
using Casamiel.Application.Commands.Waimai.v3;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace Casamiel.API.Controllers.V2.Pre
{
    /// <summary>
    /// 
    /// </summary>
    [ApiVersion("2.0")]
    [Route("api/v{api-version:apiVersion}/Pre/[controller]")]
    [ApiController]
    [Authorize]
    [EnableCors("any")]
    public class OrderController : BaseController
    {
        private readonly NLog.ILogger logger = NLog.LogManager.GetLogger("OrderService");
        private readonly IStoreService _storeService;
        private readonly IMediator _mediator;
        private readonly IMemcachedClient _memcachedClient;
        private readonly string _memcachedPrex;
        private readonly IIcApiService _icApiService;
        public OrderController(IMediator mediator, IStoreService storeService, IIcApiService icApiService, INetICService netICService, IMemcachedClient memcachedClient, IOptionsSnapshot<CasamielSettings> optionsSnapshot)
        {
            if (optionsSnapshot is null) {
                throw new ArgumentNullException(nameof(optionsSnapshot));
            }

            _mediator = mediator;
            _storeService = storeService;
            _memcachedClient = memcachedClient;
            _memcachedPrex = optionsSnapshot.Value.MemcachedPre;
            _icApiService = icApiService;
        }

        /// <summary>
        /// 预点单下单
        /// </summary>
        /// <param name="req"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        [HttpPost]
        [Route("[action]")]
        public async Task<BaseResult<PaymentRsp>> CreateOrder([FromBody] OrderCreateRequest req, [FromHeader(Name = "u-token")] string token)
        {
            if (req == null) {
                throw new ArgumentNullException(nameof(req));
            }

            var Logininfo = this.LoginInfo;
            var mobile = MemberHelper.GetMobile(token);

            var cmd = new CreateOrderCommand(Logininfo.Item3) {
                
                PayCardNO = req.PayCardNO,
                Paymethod = req.Paymethod,

                ContactName = req.ContactName,

                GoodsList = req.GoodsList,
                Mobile = mobile,

                StoreId = req.StoreId,
                Id = req.Id,
                DiscountList = req.DiscountList,
                ContactPhone = req.ContactPhone,
                InvoiceId = req.InvoiceId,
                Remark = req.Remark
            };
            var result = await _mediator.Send(cmd).ConfigureAwait(false);
            logger.Trace($"req:{JsonConvert.SerializeObject(cmd)},{JsonConvert.SerializeObject(result)}");
            if (result.Code == 0 && result.Content.Payed != true) {
                logger.Trace($"{JsonConvert.SerializeObject(result.Content)}");
                var array = result.Content.Paymentrequest.Split(',');
                var p_tradeno = $"C{DateTime.Now.ToString("yyMMddHHmmssfff", CultureInfo.CurrentCulture)}";
                var payment = new PaymentRecord {
                    ShopName = "",
                    OperationMethod = (int)OperationMethod.Pre,
                    TradeNo = p_tradeno,
                    Amount = array[0].ToDouble(0),
                    PayMethod = req.Paymethod,
                    BillNO = result.Content.OrderCode,
                    IcTradeNO = array[1].ToString(CultureInfo.CurrentCulture),
                    State = 0,
                    OperationState = 0,
                    CreateTime = DateTime.Now,
                    Mobile = mobile
                };

                string shopno;
                var shopinfo = await _storeService.GetByStoreIdAsync<ICasaMielSession>(req.StoreId).ConfigureAwait(false);
                if (shopinfo != null) {
                    payment.ShopName = shopinfo.StoreName;
                    payment.ShopId = shopinfo.RelationId;
                }


                var cachekey = string.Format(CultureInfo.CurrentCulture, Constant.SHOPNO, _memcachedPrex, payment.ShopId);
                shopno = await _memcachedClient.GetValueAsync<string>(cachekey).ConfigureAwait(false);
                if (string.IsNullOrEmpty(shopno)) {
                    var basedata = await _icApiService.BasedataQuery(new BasedataqueryReq { Datatype = 3, Datavalue = $"{payment.ShopId.Value}" }).ConfigureAwait(false);
                    if (basedata.code == 0) {
                        var d = JsonConvert.DeserializeObject<JArray>(basedata.content);
                        if (d.Count > 0) {
                            shopno = d[0]["no"].ToString();
                            await _memcachedClient.AddAsync(cachekey, shopno, 72000).ConfigureAwait(false);
                        }
                    }
                }
                payment.ShopNO = shopno;

                var command = new Application.Commands.CreatePaymentRequestCommand(payment, req.Id, PaymentScenario.Waimai);
                var result1 = await _mediator.Send(command).ConfigureAwait(false);

                var pay = new PaymentRsp {
                    OrderCode = result1.Ordercode,
                    Payed = result1.Payed,
                    Paymentrequest = result1.Paymentrequest,
                    PayMethod = result1.PayMethod.ToInt32(0)
                };
                return new BaseResult<PaymentRsp>(pay, 0, "");
            } else if (result.Content.Payed) {
                var orderdetail = new GetOrderDetailCommand(mobile, result.Content.OrderCode,LoginInfo.Item3);
                var rsp = await _mediator.Send(orderdetail).ConfigureAwait(false);
                if (rsp.Code == 0) {
                    var storeentity = await _storeService.GetByStoreIdAsync<ICasaMielSession>(req.StoreId).ConfigureAwait(false);
                    var precommd = new PreOrderPaySucessSubscribeMessageCommand {  OrderCode=orderdetail.OrderCode, Mobile = mobile };
                    precommd.Data = new string[] { rsp.Content.TakeCode, storeentity?.StoreName, storeentity?.FullAddress, $"¥{rsp.Content.PayMoney.ToString("#", CultureInfo.CurrentCulture)}", "已下单" };
                    await _mediator.Send(precommd).ConfigureAwait(false);

                }

            }
            return result;

        }

        /// <summary>
        /// 预点单前置订单信息
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        public async Task<BaseResult<OrderInformationReponse>> GetPreOrderInformation(GetPreOrderInformationRequest request)
        {
            if (request is null) {
                throw new ArgumentNullException(nameof(request));
            }

            var cmd = new GetPreOrderInformationCommand { StoreId = request.StoreId };
            return await _mediator.Send(cmd).ConfigureAwait(false);
        }



    }
}
